# -*- coding:utf-8 -*-
import sys,os
import re

version = 'alpha1'

regex_ext_mask = re.compile(r'(.*.h$)|(.*.c$)|(.*.cpp$)|(.*.hpp$)')
regex_empty_line = re.compile(r'^[ \t\n]+$')
regex_comment  = re.compile(r'/\*[\w\W]+?\*/')
regex_cpp_comment = re.compile(r'[\t ]*//.+');

def count_lines(filename):
    #注释的行数
    lines_comment = 0
    #空行数
    lines_empty = 0
    #代码行数
    lines_code  = 0

    #用于保存去掉注释后引入的空行
    lines_strip_comments = 0

    fin = open(filename)
    data  = fin.read()
    fin.close()

    #统计c风格的注释
    comments = regex_comment.findall(data)
    lines_strip_comments += len(comments)
    for comment in comments:
        lines_comment += len(comment.split('\n'))

    no_c_comments = regex_comment.sub('', data)

    #统计c++风格的注释
    comments = regex_cpp_comment.findall(no_c_comments)
    lines_strip_comments += len(comments)
    lines_comment += len(comments)
    no_cpp_comments = regex_cpp_comment.sub('', no_c_comments)

    #统计代码和空行
    lines = no_cpp_comments.split('\n')
    for line in lines:
        if len(line) == 0 or regex_empty_line.match(line):
            lines_empty += 1
        else:
            lines_code += 1

    return {'code':lines_code, 
            'comment':lines_comment,
            'empty':lines_empty,
            'nr_comments':lines_strip_comments}

def pretty_digit(d):
    dlist = []
    while d > 1000:
        dlist.append(d % 1000)
        d = d /1000
    if d > 0:
        dlist.append(d)

    #反向输出
    s = ''
    for value in reversed(dlist):
        s += '%d,' % value

    return s[:-1]

def walk_and_count(topdir):
    print '-' * 80
    print ' (%8s, %8s, %8s) filepath' % ('codes', 'empty', 'comment')
    lines_empty    = 0
    lines_comment  = 0
    lines_code     = 0
    nr_comments    = 0;

    for root,dirs,files in os.walk(topdir):
        for file in files:
            fullpath = os.path.join(root, file)
            if regex_ext_mask.match(fullpath):
                res = count_lines(fullpath)
                lines_code    += res['code']
                lines_comment += res['comment']
                lines_empty   += res['empty']
                nr_comments   += res['nr_comments']
                print ' (%8d, %8d, %8d) %s' % \
                        (res['code'],res['empty'],res['comment'],fullpath)
            pass
        pass

    print '-' * 80
    print 'Lines Summary:'
    print '        code lines = %10s' % pretty_digit(lines_code)
    print '       empty lines = %10s' % pretty_digit(lines_empty)
    print '     comment lines = %10s' % pretty_digit(lines_comment)
    print 'number of comments = %10s (included in empty lines sometime!)' % pretty_digit(nr_comments)

if __name__ == '__main__':
    if len(sys.argv) != 2:
        print version
        print 'usage:'
        print ' script.py top_dir'
    else:
        walk_and_count(sys.argv[1])
